@@ -0,0 +1,38 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from __future__ import division |
|
4 |
+ |
|
5 |
+from django_logit import logit |
|
6 |
+from django_query import get_query_value |
|
7 |
+from django_response import response |
|
8 |
+ |
|
9 |
+from api.wx_views import get_point_limit_scene_qrcode_url |
|
10 |
+from equipment.models import IsolationPointFieldPoolInfo, IsolationPointInfo |
|
11 |
+from utils.error.errno_utils import IsolationPointStatusCode |
|
12 |
+ |
|
13 |
+ |
|
14 |
+@logit |
|
15 |
+def field_default(request): |
|
16 |
+ fields = IsolationPointFieldPoolInfo.objects.filter(status=True) |
|
17 |
+ fields = [f.data for f in fields] |
|
18 |
+ |
|
19 |
+ return response(data={ |
|
20 |
+ 'fields': fields, |
|
21 |
+ }) |
|
22 |
+ |
|
23 |
+ |
|
24 |
+@logit |
|
25 |
+def point_field_update(request): |
|
26 |
+ point_id = request.POST.get('point_id', '') |
|
27 |
+ fields = get_query_value(request, 'fields', val_cast_type='listjson') |
|
28 |
+ |
|
29 |
+ try: |
|
30 |
+ point = IsolationPointInfo.objects.get(point_id=point_id, status=True) |
|
31 |
+ except IsolationPointInfo.DoesNotExist: |
|
32 |
+ return response(IsolationPointStatusCode.ISOLATIONPOINT_NOT_FOUND) |
|
33 |
+ |
|
34 |
+ point.point_fields = fields |
|
35 |
+ point.limit_scene_qrcode_url = get_point_limit_scene_qrcode_url(point_id) |
|
36 |
+ point.save() |
|
37 |
+ |
|
38 |
+ return response() |
@@ -27,6 +27,18 @@ def measure_window(request): |
||
27 | 27 |
|
28 | 28 |
|
29 | 29 |
@logit |
30 |
+def get_point_info(request): |
|
31 |
+ point_id = request.POST.get('point_id', '') |
|
32 |
+ |
|
33 |
+ try: |
|
34 |
+ point = IsolationPointInfo.objects.get(point_id=point_id, status=True) |
|
35 |
+ except IsolationPointInfo.DoesNotExist: |
|
36 |
+ return response(IsolationPointStatusCode.ISOLATIONPOINT_NOT_FOUND) |
|
37 |
+ |
|
38 |
+ return response(data=point.data) |
|
39 |
+ |
|
40 |
+ |
|
41 |
+@logit |
|
30 | 42 |
def get_point_fields(request): |
31 | 43 |
point_id = request.POST.get('point_id', '') |
32 | 44 |
|
@@ -2,7 +2,7 @@ |
||
2 | 2 |
|
3 | 3 |
from django.conf.urls import url |
4 | 4 |
|
5 |
-from api import admin_views, eqpt_views, mini_views, oauth_views, point_views |
|
5 |
+from api import admin_views, eqpt_views, field_views, mini_views, oauth_views, point_views, wx_views |
|
6 | 6 |
|
7 | 7 |
|
8 | 8 |
urlpatterns = [ |
@@ -14,11 +14,24 @@ urlpatterns += [ |
||
14 | 14 |
] |
15 | 15 |
|
16 | 16 |
urlpatterns += [ |
17 |
+ url(r'^get_limit_scene_qrcode_url$', wx_views.get_limit_scene_qrcode_url, name='get_limit_scene_qrcode_url'), |
|
18 |
+] |
|
19 |
+ |
|
20 |
+urlpatterns += [ |
|
17 | 21 |
url(r'^admin/login$', admin_views.admin_login, name='admin_login'), |
18 | 22 |
] |
19 | 23 |
|
20 | 24 |
urlpatterns += [ |
25 |
+ url(r'^field/default$', field_views.field_default, name='field_default'), |
|
26 |
+ |
|
27 |
+ url(r'^point/field/add$', field_views.point_field_update, name='point_field_add'), |
|
28 |
+ url(r'^point/field/update$', field_views.point_field_update, name='point_field_update'), |
|
29 |
+] |
|
30 |
+ |
|
31 |
+urlpatterns += [ |
|
21 | 32 |
url(r'^point/measure_window$', point_views.measure_window, name='measure_window'), |
33 |
+ |
|
34 |
+ url(r'^point/info$', point_views.get_point_info, name='point_info'), |
|
22 | 35 |
] |
23 | 36 |
|
24 | 37 |
urlpatterns += [ |
@@ -40,6 +53,7 @@ urlpatterns += [ |
||
40 | 53 |
] |
41 | 54 |
|
42 | 55 |
urlpatterns += [ |
56 |
+ url(r'^mp/get_point_info$', point_views.get_point_info, name='get_point_info'), |
|
43 | 57 |
url(r'^mp/get_point_fields$', point_views.get_point_fields, name='get_point_fields'), |
44 | 58 |
url(r'^mp/save_point_fields$', point_views.save_point_fields, name='save_point_fields'), |
45 | 59 |
url(r'^mp/bind_eqpt$', point_views.bind_eqpt, name='bind_eqpt'), |
@@ -0,0 +1,49 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from __future__ import division |
|
4 |
+ |
|
5 |
+from django.conf import settings |
|
6 |
+from django_response import response |
|
7 |
+from pywe_qrcode import qrcode_limit_str_scene |
|
8 |
+from pywe_storage import RedisStorage |
|
9 |
+ |
|
10 |
+from utils.error.errno_utils import ParamStatusCode |
|
11 |
+from utils.redis.connect import r |
|
12 |
+ |
|
13 |
+ |
|
14 |
+def get_limit_scene_qrcode_url(request): |
|
15 |
+ scene = str(request.GET.get('scene', '')) |
|
16 |
+ |
|
17 |
+ if not scene: |
|
18 |
+ return response(ParamStatusCode.PARAM_NOT_FOUND) |
|
19 |
+ |
|
20 |
+ JSAPI = settings.WECHAT.get('JSAPI', {}) |
|
21 |
+ |
|
22 |
+ appid = JSAPI.get('appID', '') |
|
23 |
+ appsecret = JSAPI.get('appsecret', '') |
|
24 |
+ |
|
25 |
+ if not appid: |
|
26 |
+ return response(ParamStatusCode.PARAM_NOT_FOUND) |
|
27 |
+ |
|
28 |
+ qrurl = qrcode_limit_str_scene(scene_str=scene, appid=appid, secret=appsecret, storage=RedisStorage(r), qrurl=True) |
|
29 |
+ |
|
30 |
+ return response(data={ |
|
31 |
+ 'qrurl': qrurl, |
|
32 |
+ }) |
|
33 |
+ |
|
34 |
+ |
|
35 |
+def get_point_limit_scene_qrcode_url(scene): |
|
36 |
+ if not scene: |
|
37 |
+ return '' |
|
38 |
+ |
|
39 |
+ JSAPI = settings.WECHAT.get('JSAPI', {}) |
|
40 |
+ |
|
41 |
+ appid = JSAPI.get('appID', '') |
|
42 |
+ appsecret = JSAPI.get('appsecret', '') |
|
43 |
+ |
|
44 |
+ if not appid: |
|
45 |
+ return '' |
|
46 |
+ |
|
47 |
+ qrurl = qrcode_limit_str_scene(scene_str=scene, appid=appid, secret=appsecret, storage=RedisStorage(r), qrurl=True, useurl=True) |
|
48 |
+ |
|
49 |
+ return qrurl |
@@ -3,8 +3,12 @@ |
||
3 | 3 |
from django.contrib import admin |
4 | 4 |
from django_admin import ReadOnlyModelAdmin |
5 | 5 |
|
6 |
-from equipment.models import (IsolationPointInfo, IsolationPointUserInfo, ThermometerEquipmentInfo, |
|
7 |
- ThermometerMeasureInfo, ThermometerMeasureLogInfo) |
|
6 |
+from equipment.models import (IsolationPointFieldPoolInfo, IsolationPointInfo, IsolationPointUserInfo, |
|
7 |
+ ThermometerEquipmentInfo, ThermometerMeasureInfo, ThermometerMeasureLogInfo) |
|
8 |
+ |
|
9 |
+ |
|
10 |
+class IsolationPointFieldPoolInfoAdmin(admin.ModelAdmin): |
|
11 |
+ list_display = ('field_type', 'field_key', 'field_name', 'field_options', 'status', 'updated_at', 'created_at') |
|
8 | 12 |
|
9 | 13 |
|
10 | 14 |
class IsolationPointInfoAdmin(admin.ModelAdmin): |
@@ -30,6 +34,7 @@ class ThermometerMeasureLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin): |
||
30 | 34 |
list_filter = ('point_id', 'temperature_src', 'status') |
31 | 35 |
|
32 | 36 |
|
37 |
+admin.site.register(IsolationPointFieldPoolInfo, IsolationPointFieldPoolInfoAdmin) |
|
33 | 38 |
admin.site.register(IsolationPointInfo, IsolationPointInfoAdmin) |
34 | 39 |
admin.site.register(IsolationPointUserInfo, IsolationPointUserInfoAdmin) |
35 | 40 |
admin.site.register(ThermometerEquipmentInfo, ThermometerEquipmentInfoAdmin) |
@@ -0,0 +1,31 @@ |
||
1 |
+# Generated by Django 3.2.6 on 2021-08-14 19:56 |
|
2 |
+ |
|
3 |
+from django.db import migrations, models |
|
4 |
+import jsonfield.fields |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class Migration(migrations.Migration): |
|
8 |
+ |
|
9 |
+ dependencies = [ |
|
10 |
+ ('equipment', '0006_auto_20210812_1357'), |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.CreateModel( |
|
15 |
+ name='IsolationPointFieldPoolInfo', |
|
16 |
+ fields=[ |
|
17 |
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|
18 |
+ ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')), |
|
19 |
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')), |
|
20 |
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')), |
|
21 |
+ ('field_type', models.CharField(choices=[('input', 'input'), ('select', 'select'), ('file', 'file')], default='input', help_text='字段类型', max_length=8, verbose_name='field_type')), |
|
22 |
+ ('field_name', models.CharField(blank=True, help_text='字段名称', max_length=32, null=True, verbose_name='field_name')), |
|
23 |
+ ('field_key', models.CharField(blank=True, help_text='字段键值', max_length=32, null=True, verbose_name='field_key')), |
|
24 |
+ ('field_options', jsonfield.fields.JSONField(blank=True, default=[], help_text='字段选择', null=True, verbose_name='field_options')), |
|
25 |
+ ], |
|
26 |
+ options={ |
|
27 |
+ 'verbose_name': '用户字段池信息', |
|
28 |
+ 'verbose_name_plural': '用户字段池信息', |
|
29 |
+ }, |
|
30 |
+ ), |
|
31 |
+ ] |
@@ -7,14 +7,51 @@ from jsonfield import JSONField |
||
7 | 7 |
from shortuuidfield import ShortUUIDField |
8 | 8 |
from TimeConvert import TimeConvert as tc |
9 | 9 |
|
10 |
+from utils.redis.rqrurl import get_qrcode_url |
|
11 |
+ |
|
12 |
+ |
|
13 |
+class IsolationPointFieldPoolInfo(BaseModelMixin): |
|
14 |
+ INPUT = 'input' |
|
15 |
+ SELECT = 'select' |
|
16 |
+ FILE = 'file' |
|
17 |
+ |
|
18 |
+ FIELD_TYPE_TUPLE = ( |
|
19 |
+ (INPUT, 'input'), |
|
20 |
+ (SELECT, 'select'), |
|
21 |
+ (FILE, 'file'), |
|
22 |
+ ) |
|
23 |
+ |
|
24 |
+ # { |
|
25 |
+ # "type": "input", # input, select, file |
|
26 |
+ # "name": "", |
|
27 |
+ # "options": ["男", "女"], # type=select |
|
28 |
+ # } |
|
29 |
+ field_type = models.CharField(_('field_type'), max_length=8, choices=FIELD_TYPE_TUPLE, default=INPUT, help_text='字段类型') |
|
30 |
+ field_name = models.CharField(_('field_name'), max_length=32, blank=True, null=True, help_text='字段名称') |
|
31 |
+ field_key = models.CharField(_('field_key'), max_length=32, blank=True, null=True, help_text='字段键值') |
|
32 |
+ field_options = JSONField(_('field_options'), default=[], blank=True, null=True, help_text='字段选择') |
|
33 |
+ |
|
34 |
+ class Meta: |
|
35 |
+ verbose_name = _('用户字段池信息') |
|
36 |
+ verbose_name_plural = _('用户字段池信息') |
|
37 |
+ |
|
38 |
+ def __unicode__(self): |
|
39 |
+ return self.pk |
|
40 |
+ |
|
41 |
+ @property |
|
42 |
+ def data(self): |
|
43 |
+ return { |
|
44 |
+ 'type': self.field_type, |
|
45 |
+ 'key': self.field_key, |
|
46 |
+ 'name': self.field_name, |
|
47 |
+ 'options': self.field_options, |
|
48 |
+ } |
|
49 |
+ |
|
10 | 50 |
|
11 | 51 |
class IsolationPointInfo(BaseModelMixin): |
12 | 52 |
point_id = ShortUUIDField(_('point_id'), max_length=32, blank=True, null=True, help_text='隔离点唯一标识', db_index=True, unique=True) |
13 | 53 |
point_name = models.CharField(_('point_name'), max_length=255, blank=True, null=True, help_text='隔离点名称') |
14 | 54 |
|
15 |
- # [{"start": "8:00", "end": "9:00"}, {"start": "12:00", "end": "14:00"}] |
|
16 |
- point_measure_window = JSONField(_('point_measure_window'), default=[], blank=True, null=True, help_text='隔离点测温时间段') |
|
17 |
- |
|
18 | 55 |
# { |
19 | 56 |
# "type": "input", # input, select, file |
20 | 57 |
# "name": "", |
@@ -22,6 +59,9 @@ class IsolationPointInfo(BaseModelMixin): |
||
22 | 59 |
# } |
23 | 60 |
point_fields = JSONField(_('point_fields'), default=[], blank=True, null=True, help_text='字段列表') |
24 | 61 |
|
62 |
+ # [{"start": "8:00", "end": "9:00"}, {"start": "12:00", "end": "14:00"}] |
|
63 |
+ point_measure_window = JSONField(_('point_measure_window'), default=[], blank=True, null=True, help_text='隔离点测温时间段') |
|
64 |
+ |
|
25 | 65 |
limit_scene_qrcode_url = models.CharField(_('limit_scene_qrcode_url'), max_length=255, blank=True, null=True, help_text='字段二维码') |
26 | 66 |
|
27 | 67 |
class Meta: |
@@ -33,10 +73,13 @@ class IsolationPointInfo(BaseModelMixin): |
||
33 | 73 |
|
34 | 74 |
@property |
35 | 75 |
def data(self): |
76 |
+ qrcode_url = get_qrcode_url(self.point_id) |
|
36 | 77 |
return { |
37 | 78 |
'point_id': self.point_id, |
38 | 79 |
'point_name': self.point_name, |
80 |
+ 'point_fields': self.point_fields, |
|
39 | 81 |
'point_measure_window': self.point_measure_window, |
82 |
+ 'qrcode_url': qrcode_url, |
|
40 | 83 |
} |
41 | 84 |
|
42 | 85 |
@property |
@@ -1,4 +1,5 @@ |
||
1 | 1 |
pywe-miniapp==1.1.6 |
2 | 2 |
pywe-oauth==1.1.1 |
3 | 3 |
pywe-pay==1.0.14 |
4 |
+pywe-qrcode==1.0.3 |
|
4 | 5 |
pywe-storage==1.0.1 |
@@ -1 +1,3 @@ |
||
1 | 1 |
# -*- coding: utf-8 -*- |
2 |
+ |
|
3 |
+HY_QRCODE_URL_HASH = 'twjc:qrcode:url:hash' # scene:qrcode_url |
@@ -0,0 +1,19 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from api.wx_views import get_point_limit_scene_qrcode_url |
|
4 |
+from utils.redis.connect import r |
|
5 |
+from utils.redis.rkeys import HY_QRCODE_URL_HASH |
|
6 |
+ |
|
7 |
+ |
|
8 |
+def set_qrcode_url(scene): |
|
9 |
+ qrcode_url = get_point_limit_scene_qrcode_url(scene) |
|
10 |
+ if qrcode_url: |
|
11 |
+ try: |
|
12 |
+ r.hset(HY_QRCODE_URL_HASH, scene, qrcode_url) |
|
13 |
+ except Exception as e: |
|
14 |
+ pass |
|
15 |
+ return qrcode_url |
|
16 |
+ |
|
17 |
+ |
|
18 |
+def get_qrcode_url(scene): |
|
19 |
+ return r.hget(HY_QRCODE_URL_HASH, scene) or set_qrcode_url(scene) |